/**
 * <p>Title: OCSPUtils.java</p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2019</p>
 * <p>Company: www.ahdms.com</p>
 * @author qinxiang
 * @date 2019年9月10日
 * @version 1.0
*/
package com.ahdms.es.util;

import com.ahdms.es.ocsp.OCSPRequestBuilder;
import com.ahdms.es.ocsp.OCSPResponseHandle;
import com.ahdms.es.ocsp.OCSPRespondVO;
import com.ahdms.es.ocsp.SingleCertVO;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ocsp.OCSPRequest;
import org.bouncycastle.asn1.ocsp.OCSPResponse;
import org.bouncycastle.asn1.x509.Certificate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.security.cert.CertPathValidatorException;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * Title: OCSPUtils
 * </p>
 * <p>
 * Description:
 * </p>
 *
 * @author qinxiang
 * @date 2019年9月10日
 */
public class OCSPUtils {
	private static final Logger logger = LoggerFactory.getLogger(OCSPUtils.class);

	public static Integer verifyCert(Certificate cert, Certificate pkm, String ocspUrl) {
		Integer bool = 2;
		// 获取ocsp请求证书
		try {
			// 构建ocsp请求
			List<Certificate> certs = new ArrayList<Certificate>();
			certs.add(cert);
			OCSPRequestBuilder ocspRequestBuilder = new OCSPRequestBuilder(certs, pkm);
			OCSPRequest ocspRequest = ocspRequestBuilder.build();
			byte[] requestBytes = AsnUtil.asn1ToByte(ocspRequest);
			// 获取ocsp响应
			URI responderURI = null;
			OCSPResponse ocspResponse = null;
			try {
				responderURI = new URI(ocspUrl);
				byte[] response = sendOCSP(requestBytes, responderURI);

				ASN1Sequence asn1Sequence = AsnUtil.byteToASN1Sequence(response);
				ocspResponse = OCSPResponse.getInstance(asn1Sequence);
			} catch (URISyntaxException e) {
				e.printStackTrace();
				return 1;
			} catch (CertPathValidatorException e) {
				e.printStackTrace();
				return 1;
			}
			// 解析ocsp响应
			OCSPResponseHandle handle = new OCSPResponseHandle(ocspRequest, ocspResponse);
			logger.debug("ocsp响应码：" + handle.getOCSPResponseCode());
			// 遍历多证书的状态
			OCSPRespondVO vo = handle.getCertStatusInfos(null);
			if (vo.getCertInfos().size() >= 1 && vo.getRespValue() == 0) {
				for (SingleCertVO sc : vo.getCertInfos()) {
					logger.debug("证书序列号" + sc.getSerialNumber() + "的状态" + sc.getStatus());
					if (sc.getStatus() != null) {
						bool = Integer.parseInt(sc.getStatus());
					}
				}
			} /*else {
				bool = 1;
			}*/
			logger.debug("OCSP返回状态bool=" + bool);
			return bool;

		} catch (NumberFormatException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return 1;
	}

	public static byte[] sendOCSP(byte[] requestBytes, URI responderURI)
			throws IOException, CertPathValidatorException {
		InputStream in = null;
		OutputStream out = null;
		byte[] response = null;
		try {
			URL url = responderURI.toURL();
			HttpURLConnection con = (HttpURLConnection) url.openConnection();
			con.setConnectTimeout(15000);
			con.setReadTimeout(15000);
			con.setDoOutput(true);
			con.setDoInput(true);
			con.setRequestMethod("POST");
			con.setRequestProperty("Content-type", "application/ocsp-request");
			con.setRequestProperty("Content-length", String.valueOf(requestBytes.length));
			out = con.getOutputStream();
			out.write(requestBytes);
			out.flush();
			// Check the response
			if (con.getResponseCode() != HttpURLConnection.HTTP_OK) {
				System.out.println("Received HTTP error: " + con.getResponseCode() + " - " + con.getResponseMessage());
			}
			in = con.getInputStream();
			response = ThriftTool.toByteArray(in);
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException ioe) {
					throw ioe;
				}
			}
			if (out != null) {
				try {
					out.close();
				} catch (IOException ioe) {
					throw ioe;
				}
			}
		}
		return response;
	}
}
